package 纯字符串;

public class JZ43零到n整数中1出现的次数 {

    /**
     * 输入一个整数 n ，求1～n这n个整数的十进制表示中1出现的次数。
     * 例如，输入12，1～12这些整数中包含1 的数字有1、10、11和12，1一共出现了5次。
     *
     * 示例 1：
     * 输入：n = 12
     * 输出：5
     * 示例 2：
     * 输入：n = 13
     * 输出：6
     *  
     * 限制：
     * 1 <= n < 2^31
     */

    public int countDigitOne(int n) {

        /**
         * 按照每位来算
         * 从低位算到高位;
         * 当前位:0时; count=high(高位组成的数字)*digit(当前十阶乘)
         * 当前位:1时; count=high(高位组成的数字)*digit(当前十阶乘)+low(低位组成的数字)+1
         * 当前位:其他时: count=(high+1)*digit
         *
         * 规律是得自己寻找出来的...
         */
        int digit = 1;
        int res = 0;
        int high = n / 10;
        int cur = n % 10;
        int low = 0;
        while(high != 0 || cur != 0) {
            if(cur == 0) {
                res += high * digit;
            }
            else if(cur == 1){
                res += high * digit + low + 1;
            }
            else{
                res += (high + 1) * digit;
            }
            low += (cur * digit);
            cur = high % 10;
            high /= 10;
            digit *= 10;
        }
        return res;

    }

}
